package clue

import (
	"context"
	"encoding/json"
	"errors"
	clueDto "git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/dto/clue"
	"git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/repository/clue"
	pb "git.mycaigou.com/gfyx/micro-gfyx-mp-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/clue"
)

type clueService struct {
	clueRepo clue.ClueRepositoryIface
}

// NewClueService
// 线索管理服务
func NewClueService(clueRepo clue.ClueRepositoryIface) ClueServiceIface {
	return &clueService{
		clueRepo: clueRepo,
	}
}

// AddClueSourceFollow 添加线索跟进记录
func (s *clueService) AddClueSourceFollow(ctx context.Context, request *clueDto.AddClueSourceFollowRequest) (*clueDto.AddClueSourceFollowResponse, error) {
	resp, err := s.clueRepo.AddClueSourceFollow(ctx, &pb.AddClueSourceFollowRequest{
		FollowType:      request.FollowType,
		ClueStatus:      request.ClueStatus,
		Content:         request.Content,
		FollowStatus:    request.FollowStatus,
		ContactName:     request.ContactName,
		ContactMobile:   request.ContactMobile,
		ContactPosition: request.ContactPosition,
		OrganizingCode:  request.OrganizingCode,
		CompanyName:     request.CompanyName,
		Source:          request.Source,
		SourceId:        request.SourceId,
		SourceTitle:     request.SourceTitle,
		ProvinceCode:    request.ProvinceCode,
		CityCode:        request.CityCode,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("跟进失败")
	}
	return &clueDto.AddClueSourceFollowResponse{IsNewClue: resp.IsNewClue}, nil
}

func (s *clueService) SaveClue(ctx context.Context, request *clueDto.SaveClueRequest) (*clueDto.SaveClueResponse, error) {
	resp, err := s.clueRepo.SaveClue(ctx, &pb.SaveClueRequest{
		Id:              request.Id,
		ContactName:     request.ContactName,
		ContactMobile:   request.ContactMobile,
		CompanyName:     request.CompanyName,
		OrganizingCode:  request.OrganizingCode,
		Source:          0,
		SourceId:        "",
		SourceTitle:     "",
		ProvinceCode:    request.ProvinceCode,
		CityCode:        request.CityCode,
		Status:          request.Status,
		InChargeUserId:  request.InChargeUserId,
		ContactPosition: request.ContactPosition,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Id == 0 {
		return nil, errors.New("添加线索失败")
	}

	return &clueDto.SaveClueResponse{Id: resp.Id}, nil
}

func (s *clueService) DeleteClue(ctx context.Context, id int64) (*clueDto.DeleteClueResponse, error) {
	resp, err := s.clueRepo.DeleteClue(ctx, &pb.DeleteClueRequest{Id: id})
	if err != nil {
		return nil, err
	}
	if resp == nil || !resp.IsSuccess {
		return nil, errors.New("删除线索失败")
	}
	return &clueDto.DeleteClueResponse{IsSuccess: resp.IsSuccess}, nil
}

func (s *clueService) GetClueDetailById(ctx context.Context, id int64) (*clueDto.GetClueDetailByIdResponse, error) {
	resp, err := s.clueRepo.GetClueDetail(ctx, &pb.GetClueDetailByClueIdRequest{
		Id: id,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Clue == nil {
		return nil, errors.New("获取线索详情失败")
	}
	clueDetail := resp.Clue
	result := &clueDto.GetClueDetailByIdResponse{
		Id:               clueDetail.Id,
		ContactName:      clueDetail.ContactName,
		ContactMobile:    clueDetail.ContactMobile,
		ContactPosition:  clueDetail.ContactPosition,
		Status:           clueDetail.Status,
		CompanyName:      clueDetail.CompanyName,
		OrganizingCode:   clueDetail.OrganizingCode,
		CompanyType:      clueDetail.CompanyType,
		LegalName:        clueDetail.LegalName,
		EstablishDate:    clueDetail.EstablishDate,
		CompanyAddress:   clueDetail.CompanyAddress,
		ProvinceCode:     clueDetail.ProvinceCode,
		CityCode:         clueDetail.CityCode,
		Address:          clueDetail.Address,
		Source:           clueDetail.Source,
		SourceId:         clueDetail.SourceId,
		SourceTitle:      clueDetail.SourceTitle,
		CreatedUsername:  clueDetail.CreatedUsername,
		CreatedTime:      clueDetail.CreatedOn,
		InChargeUsername: clueDetail.InChargeUsername,
		InChargeUserId:   clueDetail.InChargeUserId,
		HasHumanFollow:   clueDetail.HasHumanFollow,
	}

	return result, nil
}

func (s *clueService) GetClueList(ctx context.Context, request *clueDto.GetClueListRequest) (*clueDto.GetClueListResponse, error) {
	resp, err := s.clueRepo.GetClueList(ctx, &pb.GetClueListRequest{
		Keyword:            request.Keyword,
		Page:               request.Page,
		PageSize:           request.PageSize,
		StatusList:         request.Status,
		AreaCodeList:       request.AreaCodes,
		UseCase:            request.UseCase,
		InChargeUserIdList: request.InChargeUserIds,
		Assigned:           request.Assigned,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取线索列表失败")
	}

	result := &clueDto.GetClueListResponse{
		Total: resp.Total,
		List:  make([]*clueDto.ClueListItem, 0),
	}
	for _, clueItem := range resp.List {
		var latestFollowInfo *clueDto.FollowInfo
		if clueItem.LatestFollow != nil {
			latestFollowInfo = &clueDto.FollowInfo{
				FollowTime:   clueItem.LatestFollow.FollowTime,
				Content:      clueItem.LatestFollow.Content,
				FollowerName: clueItem.LatestFollow.Username,
			}
		}
		result.List = append(result.List, &clueDto.ClueListItem{
			Id:               clueItem.Id,
			ContactName:      clueItem.ContactName,
			ContactMobile:    clueItem.ContactMobile,
			ContactPosition:  clueItem.ContactPosition,
			Status:           clueItem.Status,
			CompanyName:      clueItem.CompanyName,
			OrganizingCode:   clueItem.OrganizingCode,
			Source:           clueItem.Source,
			SourceId:         clueItem.SourceId,
			SourceTitle:      clueItem.SourceTitle,
			CreatedUsername:  clueItem.CreatedUsername,
			CreatedTime:      clueItem.CreatedOn,
			Address:          clueItem.Address,
			InChargeUsername: clueItem.InChargeUsername,
			HasHumanFollow:   clueItem.HasHumanFollow,
			LatestFollow:     latestFollowInfo,
		})
	}
	return result, nil
}

func (s *clueService) SaveClueTracker(ctx context.Context, request *clueDto.SaveClueTrackerRequest) (*clueDto.SaveClueTrackerResponse, error) {
	resp, err := s.clueRepo.SaveClueTracker(ctx, &pb.SaveClueTrackerRequest{
		ClueId: request.ClueId,
		UserId: request.UserId,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Id == 0 {
		return nil, errors.New("添加跟进人失败")
	}
	return &clueDto.SaveClueTrackerResponse{Id: resp.Id}, nil
}

func (s *clueService) GetClueTrackerList(ctx context.Context, request *clueDto.GetClueTrackerListRequest) (*clueDto.GetClueTrackerListResponse, error) {
	resp, err := s.clueRepo.GetClueTrackerList(ctx, &pb.GetClueTrackerListRequest{
		ClueId:   request.ClueId,
		Page:     request.Page,
		PageSize: request.PageSize,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取跟进人列表失败")
	}
	result := &clueDto.GetClueTrackerListResponse{
		Total: resp.Total,
		List:  make([]*clueDto.ClueTracker, 0),
	}
	for _, clueTrackerItem := range resp.List {
		result.List = append(result.List, &clueDto.ClueTracker{
			Id:         clueTrackerItem.Id,
			ClueId:     clueTrackerItem.ClueId,
			UserId:     clueTrackerItem.UserId,
			Name:       clueTrackerItem.Name,
			IsInCharge: clueTrackerItem.IsInCharge,
		})
	}
	return result, nil
}

func (s *clueService) DeleteClueTracker(ctx context.Context, request *clueDto.DeleteClueTrackerRequest) (*clueDto.DeleteClueTrackerResponse, error) {
	resp, err := s.clueRepo.DeleteClueTracker(ctx, &pb.DeleteClueTrackerRequest{Id: request.Id})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.IsSuccess == false {
		return nil, errors.New("删除跟进人失败")
	}
	return &clueDto.DeleteClueTrackerResponse{IsSuccess: resp.IsSuccess}, nil
}

func (s *clueService) ReplaceChargeUser(ctx context.Context, request *clueDto.ReplaceChargeUserRequest) (*clueDto.ReplaceChargeUserResponse, error) {
	resp, err := s.clueRepo.ReplaceChargeUser(ctx, &pb.ReplaceChargeUserRequest{
		ClueId: request.ClueId,
		UserId: request.UserId,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.IsSuccess == false {
		return nil, errors.New("更换负责人失败")
	}
	return &clueDto.ReplaceChargeUserResponse{IsSuccess: resp.IsSuccess}, nil
}

func (s *clueService) GetInChargeUserList(ctx context.Context) (*clueDto.GetInChargeUserListResponse, error) {
	resp, err := s.clueRepo.GetInChargeUserList(ctx, &pb.GetInChargeUserListRequest{})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取负责人列表失败")
	}

	respDto := &clueDto.GetInChargeUserListResponse{
		List:  []*clueDto.InChargeUserInfo{},
		Total: resp.Total,
	}
	for _, item := range resp.List {
		respDto.List = append(respDto.List, &clueDto.InChargeUserInfo{
			UserId: item.UserId,
			Name:   item.Name,
		})
	}
	return respDto, nil
}

func (s *clueService) SaveClueContact(ctx context.Context, request *clueDto.SaveClueContactRequest) (*clueDto.SaveClueContactResponse, error) {
	resp, err := s.clueRepo.SaveClueContact(ctx, &pb.SaveClueContactRequest{
		Id:          request.Id,
		ClueId:      request.ClueId,
		Name:        request.Name,
		Mobile:      request.Mobile,
		Position:    request.Position,
		CompanyName: request.CompanyName,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Id == 0 {
		return nil, errors.New("添加联系人失败")
	}
	return &clueDto.SaveClueContactResponse{Id: resp.Id}, nil
}

func (s *clueService) DeleteClueContact(ctx context.Context, request *clueDto.DeleteClueContactRequest) (*clueDto.DeleteClueContactResponse, error) {
	resp, err := s.clueRepo.DeleteClueContact(ctx, &pb.DeleteClueContactRequest{Id: request.Id})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.IsSuccess == false {
		return nil, errors.New("删除联系人失败")
	}
	return &clueDto.DeleteClueContactResponse{IsSuccess: resp.IsSuccess}, nil
}

func (s *clueService) GetClueContactList(ctx context.Context, request *clueDto.GetClueContactListRequest) (*clueDto.GetClueContactListResponse, error) {
	resp, err := s.clueRepo.GetClueContactList(ctx, &pb.GetClueContactListRequest{
		ClueId:   request.ClueId,
		Page:     request.Page,
		PageSize: request.PageSize,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取联系人列表失败")
	}

	result := &clueDto.GetClueContactListResponse{
		Total: resp.Total,
		List:  make([]*clueDto.ClueContact, 0),
	}
	for _, clueContactItem := range resp.List {
		result.List = append(result.List, &clueDto.ClueContact{
			Id:          clueContactItem.Id,
			ClueId:      clueContactItem.ClueId,
			Name:        clueContactItem.Name,
			Mobile:      clueContactItem.Mobile,
			Position:    clueContactItem.Position,
			CompanyName: clueContactItem.CompanyName,
		})
	}
	return result, nil
}

func (s *clueService) GetClueContactDetailById(ctx context.Context, request *clueDto.GetClueContactDetailByIdRequest) (*clueDto.GetClueContactDetailByIdResponse, error) {
	resp, err := s.clueRepo.GetClueContactDetailById(ctx, &pb.GetClueContactDetailByIdRequest{Id: request.Id})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Detail == nil {
		return nil, errors.New("获取联系人详情失败")
	}
	return &clueDto.GetClueContactDetailByIdResponse{ClueContact: clueDto.ClueContact{
		Id:          resp.Detail.Id,
		ClueId:      resp.Detail.ClueId,
		Name:        resp.Detail.Name,
		Mobile:      resp.Detail.Mobile,
		Position:    resp.Detail.Position,
		CompanyName: resp.Detail.CompanyName,
	}}, nil
}

func (s *clueService) AddClueFollowRecord(ctx context.Context, request *clueDto.AddClueFollowRecordRequest) (*clueDto.AddClueFollowRecordResponse, error) {
	resp, err := s.clueRepo.AddClueFollowRecord(ctx, &pb.AddClueFollowRecordRequest{
		ClueId:     request.ClueId,
		FollowType: request.FollowType,
		ClueStatus: request.ClueStatus,
		ContactId:  request.ContactId,
		Content:    request.Content,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil || resp.Id == 0 {
		return nil, errors.New("添加跟进记录失败")
	}
	return &clueDto.AddClueFollowRecordResponse{Id: resp.Id}, nil
}

func (s *clueService) GetClueFollowRecordList(ctx context.Context, request *clueDto.GetClueFollowRecordListRequest) (*clueDto.GetClueFollowRecordListResponse, error) {
	resp, err := s.clueRepo.GetClueFollowRecordList(ctx, &pb.GetClueFollowRecordListRequest{
		ClueId: request.ClueId, Page: request.Page, PageSize: request.PageSize,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("获取跟进记录列表失败")
	}
	result := &clueDto.GetClueFollowRecordListResponse{
		Total: resp.Total,
		List:  make([]*clueDto.ClueFollowRecord, 0),
	}
	for _, clueFollowRecordItem := range resp.List {
		var talkContent []string
		if clueFollowRecordItem.TalkContent != "" {
			_ = json.Unmarshal([]byte(clueFollowRecordItem.TalkContent), &talkContent)
		}
		result.List = append(result.List, &clueDto.ClueFollowRecord{
			Id:              clueFollowRecordItem.Id,
			ClueId:          clueFollowRecordItem.ClueId,
			FollowType:      clueFollowRecordItem.FollowType,
			FollowStatus:    clueFollowRecordItem.FollowStatus,
			ClueStatus:      clueFollowRecordItem.ClueStatus,
			ContactId:       clueFollowRecordItem.ContactId,
			ContactName:     clueFollowRecordItem.ContactName,
			ContactMobile:   clueFollowRecordItem.ContactMobile,
			Content:         clueFollowRecordItem.Content,
			TalkContent:     talkContent,
			CreatedOn:       clueFollowRecordItem.CreatedOn,
			CreatedUsername: clueFollowRecordItem.CreatedUsername,
		})
	}
	return result, nil
}

func (s *clueService) ExportClueList(ctx context.Context, request *clueDto.ExportClueListRequest) (*clueDto.ExportClueListResponse, error) {
	resp, err := s.clueRepo.ExportClueList(ctx, &pb.ExportClueListRequest{
		Keyword:            request.Keyword,
		StatusList:         request.Status,
		AreaCodeList:       request.AreaCodes,
		UseCase:            request.UseCase,
		InChargeUserIdList: request.InChargeUserIds,
		Assigned:           request.Assigned,
	})
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("导出失败")
	}

	return &clueDto.ExportClueListResponse{
		JobId: resp.JobId,
	}, nil
}

func (s *clueService) MyClueStat(ctx context.Context) (map[string]int32, error) {
	listReq := &pb.GetClueListRequest{
		UseCase:  1,
		Page:     1,
		PageSize: 1,
	}
	result := map[string]int32{"follow_count": 0, "intent_count": 0, "report_count": 0}
	listReq.StatusList = []int32{2} //跟进中
	resp, err := s.clueRepo.GetClueList(ctx, listReq)
	if err != nil {
		return nil, err
	}
	if resp != nil && resp.Total > 0 {
		result["follow_count"] = resp.Total
	}

	listReq.StatusList = []int32{3} //有意向
	resp, err = s.clueRepo.GetClueList(ctx, listReq)
	if err != nil {
		return nil, err
	}
	if resp != nil && resp.Total > 0 {
		result["intent_count"] = resp.Total
	}
	listReq.StatusList = []int32{4} //已报备
	resp, err = s.clueRepo.GetClueList(ctx, listReq)
	if err != nil {
		return nil, err
	}
	if resp != nil && resp.Total > 0 {
		result["report_count"] = resp.Total
	}
	return result, nil
}
